# twitter_bot/twitter_forwarder.py (基于Filtered Stream的修正版)
import tweepy
import yaml
import logging
import time

# --- 全局配置 ---
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
CONFIG = {}

def load_config():
    """从文件加载配置"""
    global CONFIG
    try:
        with open('config.yaml', 'r', encoding='utf-8') as f:
            CONFIG = yaml.safe_load(f)
        logging.info("配置已加载。")
        return True
    except Exception as e:
        logging.error(f"加载配置时出错: {e}")
        return False

def get_monitored_users():
    """从文件加载监控用户列表"""
    try:
        with open(CONFIG['monitor_users_file'], 'r', encoding='utf-8') as f:
            users = [line.strip().lower() for line in f if line.strip() and not line.strip().startswith('#')]
            logging.info(f"监控用户列表: {users}")
            return users
    except Exception as e:
        logging.error(f"加载监控用户列表时出错: {e}")
        return []

def setup_stream_rules(client: tweepy.Client, users_to_monitor: list):
    """设置或更新筛选流的规则"""
    logging.info("正在设置流规则...")
    
    # 1. 获取并删除现有规则
    try:
        response = client.get_rules()
        existing_rules = response.data
        if existing_rules:
            existing_rule_ids = [rule.id for rule in existing_rules]
            logging.info(f"找到 {len(existing_rule_ids)} 条现有规则，正在删除...")
            client.delete_rules(existing_rule_ids)
            logging.info("旧规则已清除。")
        else:
            logging.info("没有找到现有规则。")
    except tweepy.errors.TweepyException as e:
        logging.error(f"获取或删除规则时出错: {e}")
        return False

    # 2. 创建并添加新规则
    if not users_to_monitor:
        logging.warning("监控用户列表为空，未添加任何新规则。")
        return True
        
    new_rules = [tweepy.StreamRule(f"from:{user} -is:retweet -is:reply", tag=user) for user in users_to_monitor]
    try:
        response = client.add_rules(new_rules)
        if response.errors:
            for error in response.errors:
                logging.error(f"添加规则 '{error['value']}' 失败: {error['detail']}")
            return False
        logging.info("新规则已成功设置！")
        if response.data:
            for rule in response.data:
                logging.info(f"  - Rule ID: {rule.id}, Tag: {rule.tag}, Value: {rule.value}")
        return True
    except tweepy.errors.TweepyException as e:
        logging.error(f"添加新规则时出错: {e}")
        return False

class ForwarderStream(tweepy.StreamingClient):
    """自定义的流客户端，用于接收和处理推文"""
    def __init__(self, bearer_token, **kwargs):
        super().__init__(bearer_token, **kwargs)
        self.post_client = self.get_posting_client()
        if not self.post_client:
            raise Exception("无法初始化用于发推的客户端。")

    def get_posting_client(self):
        """创建一个用于发推的v2客户端"""
        try:
            return tweepy.Client(
                consumer_key=CONFIG['api_key'],
                consumer_secret=CONFIG['api_key_secret'],
                access_token=CONFIG['access_token'],
                access_token_secret=CONFIG['access_token_secret']
            )
        except Exception as e:
            logging.error(f"创建发推客户端失败: {e}")
            return None

    def on_connect(self):
        logging.info("✅ 成功连接到 Twitter Filtered Stream。")

    def on_disconnect(self):
        logging.warning("🔌 连接已断开。")

    def on_tweet(self, tweet: tweepy.Tweet):
        """当收到符合规则的推文时，此方法被调用"""
        try:
            author_username = tweet.matching_rules[0].tag
            logging.info(f"📬 收到来自 @{author_username} 的新推文 (ID: {tweet.id})")
            
            formatted_text = CONFIG.get('forward_format', "{text}").format(
                text=tweet.text, author=author_username
            )
            
            logging.info("正在转发...")
            response = self.post_client.create_tweet(text=formatted_text)
            logging.info(f"✅ 转发成功: https://twitter.com/user/status/{response.data['id']}")
            time.sleep(1)

        except Exception as e:
            logging.error(f"处理推文 {tweet.id} 时发生错误: {e}")
            
    def on_error(self, status_code):
        logging.error(f"❌ 流错误，状态码: {status_code}")
        if status_code == 429:
             logging.warning("达到速率限制，暂停60秒。")
             time.sleep(60)
        return True

def main():
    if not load_config():
        return

    # *** 关键修复 ***
    # 创建一个拥有所有凭证的健壮客户端，用于所有非流式操作，包括规则管理。
    # tweepy 会根据需要自动选择使用 Bearer Token 或 OAuth 1.0a。
    try:
        rule_manager_client = tweepy.Client(
            bearer_token=CONFIG['bearer_token'],
            consumer_key=CONFIG['api_key'],
            consumer_secret=CONFIG['api_key_secret'],
            access_token=CONFIG['access_token'],
            access_token_secret=CONFIG['access_token_secret']
        )
        me_response = rule_manager_client.get_me()
        logging.info(f"规则管理客户端以 @{me_response.data.username} 身份验证成功。")
    except Exception as e:
        logging.critical(f"创建全功能客户端失败，请检查所有5个凭证: {e}")
        return
    
    users = get_monitored_users()
    if not setup_stream_rules(rule_manager_client, users):
        logging.critical("规则设置失败，机器人无法启动。")
        return
        
    logging.info("--- 机器人启动，开始监听推文流 ---")
    
    stream = ForwarderStream(CONFIG['bearer_token'])
    try:
        # 只请求我们需要的字段，节省数据
        stream.filter(tweet_fields=["id", "text"])
    except KeyboardInterrupt:
        logging.info("机器人被手动停止。")
    except Exception as e:
        logging.critical(f"流发生致命错误: {e}")
    finally:
        stream.disconnect()
        logging.info("--- 机器人已关闭 ---")

if __name__ == "__main__":
    main()